Map = function(ctx){

	this.ctx = ctx;
	this.images = preloader.images;

	this.timesCalled= 0;

	// This is build on HOPE!
	// HOPE was false ... fuck
	// Documentation is GOOD! So you can build on that. Not on hope.
	this.rooms = [
		[	// y0
			{'n':null,'e':null,'s':[0,1,0],'w':null,'img':'hell','pos':'00'},			// x0
			{'n':null,'e':null,'s':[1,1,1],'w':null,'img':'dunkel','pos':'01'},			// x1
			{'n':null,'e':[1,0,3],'s':null,'w':null,'img':'hell','pos':'02'},			// x2
			{'n':null,'e':null,'s':[0,1,3],'w':[1,0,2],'img':'dunkel','pos':'03'},		// x3
		],
		[	// y1
			{'n':[0,0,0],'e':[0,1,1],'s':null,'w':null,'img':'dunkel','pos':'11'},			// x1
			{'n':[1,0,1],'e':null,'s':[1,2,1],'w':[0,1,0],'img':'hell','pos':'10'},			// x0
			{'n':null,'e':[1,1,3],'s':[0,2,2],'w':null,'img':'dunkel','pos':'13'},		// x3
			{'n':[0,0,3],'e':null,'s':null,'w':[1,1,2],'img':'hell','pos':'12'},			// x2
		],
		[	// y2
			{'n':null,'e':[0,2,1],'s':[0,3,1],'w':null,'img':'hell','pos':'20'},			// x0
			{'n':[1,1,1],'e':[1,2,2],'s':null,'w':[0,2,0],'img':'dunkel','pos':'21'},			// x1
			{'n':[0,1,2],'e':[0,2,3],'s':[1,3,2],'w':[1,2,1],'img':'hell','pos':'22'},			// x2
			{'n':null,'e':null,'s':null,'w':[0,2,2],'img':'dunkel','pos':'23'},		// x3
		],
		[	// y3
			{'n':[0,2,0],'e':[0,3,1],'s':[1,4,0],'w':null,'img':'dunkel','pos':'31'},			// x1
			{'n':null,'e':[0,3,2],'s':[1,4,1],'w':[0,3,0],'img':'hell','pos':'30'},			// x0
			{'n':[1,2,2],'e':[0,3,3],'s':[1,4,2],'w':[0,3,1],'img':'dunkel','pos':'33'},		// x3
			{'n':null,'e':null,'s':[1,4,3],'w':[0,3,2],'img':'hell','pos':'32'},			// x2
		],
		[	// y4
			{'n':[1,3,0],'e':null,'s':null,'w':null,'img':'hell','pos':'40'},			// x0
			{'n':[1,3,1],'e':null,'s':null,'w':null,'img':'dunkel','pos':'41'},			// x1
			{'n':[1,3,2],'e':null,'s':null,'w':null,'img':'hell','pos':'42'},			// x2
			{'n':[1,3,3],'e':null,'s':null,'w':null,'img':'dunkel','pos':'43'},		// x3
		]
	];

	this.getLayout = function(y,x,persons){

		var layout = [
				[null,null,null],
				[null,null,null],
				[null,null,null]
			],
			pm =[
				[null,null,null,null],
				[null,null,null,null],
				[null,null,null,null],
				[null,null,null,null],
				[null,null,null,null]
			],
			p = 0,
			px = 0,
			py = 0;

		if( y > this.rooms.length-1 || x > this.rooms[y].length-1 ){
			return layout;
		} else {
			layout[1][1] = this.rooms[y][x];
			layout[1][1].rel = '0';
		}

		for( p = persons.length; p; p-- ) {
			px = persons[p-1].position.x;
			py = persons[p-1].position.y;
			
			if(
					px >= x-1
				&&	px <= x+1
				&&	py >= y-1
				&&	py <= y+1 ){
				pm[py][px] = persons[p-1];
				if( px == x && py == y ) {
					layout[1][1].person = persons[p-1];
				}
			}
		}


		// Does this look crappy?
		// Actually it's very performant! Roll out every loop you have ;-)

		// North
		if( y > 0 && this.rooms[y][x]['n'] !== null ) {

			layout[0][1] = this.rooms[y-1][x];
			layout[0][1].rel = 'n';

			if( typeof pm[y-1] != 'undefined' && pm[y-1][x] !== null ) {
				layout[0][1].person = pm[y-1][x];
			} 

		}


		// East
		if( x+1 < this.rooms[y].length && this.rooms[y][x]['e'] !== null ) {

			layout[1][2] = this.rooms[y][x+1];
			layout[1][2].rel = 'e';

			if( typeof pm[y] != 'undefined' && pm[y][x+1] !== null ) {
				layout[1][2].person = pm[y][x+1];
			}

		}


		// South
		if( y+1 < this.rooms.length && this.rooms[y][x]['s'] !== null ) {

			layout[2][1] = this.rooms[y+1][x];
			layout[2][1].rel = 's';

			if( typeof pm[y+1] != 'undefined' && pm[y+1][x] !== null ) {
				layout[2][1].person = pm[y+1][x];
			}

		}

		// West
		if( x > 0 && this.rooms[y][x]['w'] !== null ) {

			layout[1][0] = this.rooms[y][x-1];
			layout[1][0].rel = 'w';

			if( typeof pm[y+1] != 'undefined' && pm[y][x-1] !== null ) {
				layout[1][0].person = pm[y][x-1];
			}

		}
		
		return layout;
	};

	this.draw = function(layout,player){

		var y = 0,
			x = 0,
			p = 0,
			k = 0,
			gx = 0,
			gy = 0,
			dirs = ['n','e','s','w'],
			fileIndex = '',
			position = null,
			rel = null,
			local = layout[1][1],
			drawWalls = [],
			drawDoors = [],
			drawPersons = [],
			line = null;

		layout[1][1] = null;

		this.drawTile(local, 1, 1);
		drawPersons.push([1,1,1,player]);
		if( typeof local.person !== 'undefined' ) {
			drawPersons.push([0,1,1,local.person]);
		}

		for( k in dirs ) {
			p = dirs[k];

			if( local[p] !== null && local[p][0] == 0 ) {
				drawDoors.push({
					'x': 1,
					'y': 1,
					'rel': p
				});

			}

		}

		for( y in layout ) {
			if( layout.hasOwnProperty(y) ){
				for( x in layout[y] ) {
					if( layout[y].hasOwnProperty(x) ) {
						position = layout[y][x];

						if( position !== null ) {
							rel = position.rel;
							if ( local[rel] !== null && local[rel][0] == 1) {
								this.drawTile(position, y, x);

								if( typeof position.person !== 'undefined' ) {
									drawPersons.push([0,y,x,position.person]);
								}


								for( k in dirs ) {
									p = dirs[k];
									
									if( position[p] === null ) {
										drawWalls.push({
											'x': x,
											'y': y,
											'rel': p
										});
									} else if( position[p][0] == 0 ) {
										drawDoors.push({
											'x': x,
											'y': y,
											'rel': p
										});

									}

								}

							}

						} else if( x != y && (x == 1 || y == 1) ) {
							if( x == 1 ) {
								if( y == 0) {
									rel = 'n';
								} else {
									rel = 's';
								}

							} else {
								if( x == 0 ) {
									rel = 'w';
								} else {

									rel = 'e';
								}
							}
							drawWalls.push({
								'x': 1,
								'y': 1,
								'rel': rel
							});
						}
					}
				}
			}
		}

		for( k = drawWalls.length ; k ; k-- ) {
			this.drawWall(drawWalls[k-1].rel,drawWalls[k-1].y,drawWalls[k-1].x);
		}
		for( k = drawDoors.length ; k ; k-- ) {
			this.drawDoor(drawDoors[k-1].rel,drawDoors[k-1].y,drawDoors[k-1].x);
		}
		for( k = drawPersons.length; k ; k-- ) {
			line = drawPersons[k-1];
			this.drawPerson(line[0],line[1],line[2],line[3]);
		}

	};

	this.getOppositeRel = function(rel) {
		switch(rel) {
			case 'n':return 's';break;
			case 'e':return 'w';break;
			case 's':return 'n';break;
			default:return 'e';break;
		}

	};

	this.drawPerson = function(position,y,x,person){

		var offsetX = 160,
			offsetY = 80,
			textOffsetX = 0;

		if( position ) {
			offsetX = 80;
			offsetY = 160;
		}

		if( person.fullname == 'You' ) {
			textOffsetX = 20;
		}

		this.ctx.drawImage(
			this.images[person.image],
			offsetX+(x*200),
			offsetY+(y*200)
		);

		this.ctx.fillStyle = '#339';
		this.ctx.font = 'bold 14px Courier,Courier new,serif';
		this.ctx.fillText(
			person.fullname,
			offsetX+(x*200)-20+textOffsetX,
			offsetY+(y*200)
		);

	}

	this.drawTile = function(position,y,x) {

		var	offsetX = 50,
			offsetY = 50;
			
		fileIndex = 'tile_'+position.img+'.png';
		this.ctx.drawImage(
			this.images[fileIndex],
			offsetX+(x*200),
			offsetY+(y*200)
		);

	};

	this.drawDoor = function(rel,y,x) {
		var	offsetX = 50,
			offsetY = 50;


		if( rel == 'n' ) {
			fileIndex = 'tuer_horiz.png';
		}

		if( rel == 'e' ) {
			offsetX += 180;
			fileIndex = 'tuer_vert.png';
		}

		if( rel == 's' ) {
			offsetY += 180;
			fileIndex = 'tuer_horiz.png';
		}

		if( rel == 'w' ) {
			fileIndex = 'tuer_vert.png';
		}

		this.ctx.drawImage(
			this.images[fileIndex],
			offsetX+(x*200),
			offsetY+(y*200)
		);


	};

	this.drawWall = function(rel,y,x) {

		var	offsetX = 50,
			offsetY = 50;


		if( rel == 'n' ) {
			fileIndex = 'wand_horiz.png';
		}

		if( rel == 'e' ) {
			offsetX += 180;
			fileIndex = 'wand_vert.png';
		}

		if( rel == 's' ) {
			offsetY += 180;
			fileIndex = 'wand_horiz.png';
		}

		if( rel == 'w' ) {
			fileIndex = 'wand_vert.png';
		}

		this.ctx.drawImage(
			this.images[fileIndex],
			offsetX+(x*200),
			offsetY+(y*200)
		);

	};

}